//
//  WLSocketPacketParser.m
//  WanLian
//
//  Created by 123456 on 2019/1/8.
//  Copyright © 2019 wanlian. All rights reserved.
//

#import "WLSocketPacketParser.h"
#define HEAD_DATA 0x76
#define HEAD_VERSION 0x01
#define HEAD_TYPE 0x02
extern BOOL flag;
@interface WLSocketPacketParser()
{
    dispatch_queue_t receiveQueue;
    dispatch_queue_t parserQueue;
}
//@property (nonatomic, strong) NSMutableArray *receiveData;
@property (nonatomic, strong) NSMutableData *receiveData;
@property (nonatomic, strong) NSMutableData *totalData;
@property (nonatomic, copy) ParserReultBlock parserResBlock;

@end

@implementation WLSocketPacketParser
delay_property_impl(NSMutableData, receiveData)
delay_property_impl(NSMutableData, totalData)
- (instancetype)initWithParserResultBlock:(ParserReultBlock)parserResBlock {
    if (self = [super init]) {
        self.parserResBlock = parserResBlock;
        receiveQueue = dispatch_queue_create([@"receiveQueue" UTF8String], NULL);
        parserQueue = dispatch_queue_create([@"parserQueue" UTF8String], NULL);
    }
    return self;
}
- (BOOL)headValidityJudge:(NSData *)data {
    if (data.length > 12) {
        int32_t value = [data readIntWithLocation:0];
        int32_t version = [data readIntWithLocation:4];
        int32_t msgType = [data readIntWithLocation:8];
        if (value==HEAD_DATA && version== HEAD_VERSION && msgType == HEAD_TYPE) {
            return YES;
        }
    }
    return NO;
}
- (void)resume {
    [self.receiveData removeAllData];
//    dispatch_resume(parserQueue);
}
- (void)stop {
//    dispatch_cancel(parserQueue);
//    dispatch_suspend(parserQueue);
    [self.receiveData removeAllData];
}
- (void)addData:(NSData *)data withSocket:(GCDAsyncSocket *)scoket_t tag:(long)tag {
//    LHLog(@"currentThread == %@", [NSThread currentThread]);
    int protocolHeadLen = 12;
    int protocolLen = 24;
    [self.receiveData appendData:data];
    
    if (self.receiveData.length < protocolLen) {
        return;
    }
    if ([self headValidityJudge:self.receiveData]) {
        int32_t totalLength = [self.receiveData readIntWithLocation:protocolHeadLen];
        long realPackLen = totalLength + protocolLen;
        if (self.receiveData.length - protocolLen == totalLength) {//为完全包，不需要粘包
            [self socket:scoket_t parsePackage:[self.receiveData copy] withTag:tag];
            [self.receiveData removeAllData];
        }
        else if (self.receiveData.length - protocolLen > totalLength){
            [self socket:scoket_t parsePackage:[self.receiveData subdataWithRange:NSMakeRange(0, realPackLen)] withTag:tag];
            if (self.receiveData.length > realPackLen && realPackLen >= 0) {
                NSData *leftData = [self.receiveData subdataWithRange:NSMakeRange(realPackLen, self.receiveData.length - realPackLen)];
                //            [self.receiveData removeDataWithRange:NSMakeRange(0, realPackLen)];
                //            NSData *leftData = [self.receiveData subdataWithRange:NSMakeRange(realPackLen, self.receiveData.length - realPackLen)];
                [self.receiveData removeAllData];
                if (leftData.length > 0) {
                    [self addData:leftData withSocket:scoket_t tag:tag];
                }
            }
        }
    }
    else
    {
        if (self.parserResBlock) {
            self.parserResBlock(nil, nil, WLParserStatusFail);
        }
    }
}
- (void)readData:(NSData *)data withSocket:(GCDAsyncSocket *)scoket_t tag:(long)tag{
//    LHLog(@"currentThread -- %@", [NSThread currentThread]);
    
//    [self.receiveData appendData:data];
//    LHLog(@"%ld", self.receiveData.length);
    WLWkSelf
    dispatch_async(parserQueue, ^{
        WLStrongSelf
        if (flag == NO) {
            [strongSelf addData:data withSocket:scoket_t tag:tag];
        }
    });
}


- (void)socket:(GCDAsyncSocket *)socket parsePackage:(NSData *)data withTag:(long)tag
{
    
    int protocolLen = 24;
    
    int32_t totalLength = [data readIntWithLocation:12];
    int32_t msgLength = [data readIntWithLocation:16];
    int32_t dataLength = [data readIntWithLocation:20];
    NSDictionary *msgDict = nil;
    NSData *fileData = nil;
    
    if (data.length - protocolLen == totalLength) {//为完全包，不需要粘包
        if (data.length - protocolLen >= msgLength) {
            NSData *msgData = [data subdataWithRange:NSMakeRange(protocolLen, msgLength)];
            NSString *strData = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding];
            if (!strData) {
                if (self.parserResBlock) {
                    self.parserResBlock(nil, nil, WLParserStatusFail);
                }
                return;
            }
            NSString *strTrim =[strData stringByTrimmingCharactersInSet:[NSCharacterSet controlCharacterSet]];
            NSData *dataJson = [strTrim dataUsingEncoding:NSUTF8StringEncoding];
            NSError *error;
            msgDict =[NSJSONSerialization JSONObjectWithData:dataJson options:NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments error:&error];
            if (!msgDict || error) {//解析失败
                if (self.parserResBlock) {
                    self.parserResBlock(nil, nil, WLParserStatusFail);
                }
            }
            long fileDataBeginIndex = protocolLen + msgLength;
            if (dataLength > 0 && (data.length - fileDataBeginIndex == dataLength)) {
                fileData = [data subdataWithRange:NSMakeRange(fileDataBeginIndex, dataLength)];
            }
            if (self.parserResBlock) {
                self.parserResBlock(msgDict, fileData, WLParserStatusSucess);
            }
        }
    }
}

- (void)newParser {
    
    
    /*
    NSMutableData *protocolHeadData = [NSMutableData dataWithCapacity:12];
    [protocolHeadData appendInt:HEAD_DATA];
    [protocolHeadData appendInt:HEAD_VERSION];
    [protocolHeadData appendInt:HEAD_TYPE];
    HLLog(@"!!!!!粘包数据,%lu",(unsigned long)self.receiveData.count);
    //        if (self.receiveData.count>4)//先丢包处理，可找到里面的包头再处理
    //        {
    //            [self.receiveData removeAllObjects];
    //            [self.routerSocket readDataWithTimeout:-1 tag:tag];
    //            return;
    //        }
    if (self.receiveData.count>0)
    {
        [self.receiveData addObject:data];
        NSData *dataTotal = [[self.receiveData objectAtIndex:0] subdataWithRange:NSMakeRange(protocolHeadLen, 4)];
        int totalLength = CFSwapInt32BigToHost(*(int*)([dataTotal bytes]));
        int curlen = 0;
        for (int i=0; i<self.receiveData.count; i++) {
            curlen += [[self.receiveData objectAtIndex:i] length];
        }
        LHLog(@"!!!!!缓存：totalLength == %d,curlen == %d",totalLength, curlen);
        if (curlen>=totalLength + protocolLen) {
            NSMutableData *completeData = [[NSMutableData alloc] init];
            for (int j=0; j<self.receiveData.count; j++) {
                [completeData appendData:[self.receiveData objectAtIndex:j]];
            }
            [self socket:scoket_t parsePackage:[completeData subdataWithRange:NSMakeRange(0, totalLength + protocolLen)] withTag:tag];
            [self.receiveData removeAllObjects];
            if (curlen > totalLength + protocolLen) {
                NSData *dataLeft = [completeData subdataWithRange:NSMakeRange(totalLength+protocolLen, completeData.length-totalLength-protocolLen)];
                if (dataLeft.length>=12)
                {
                    LHLog(@"!!!!!left data:%ld",dataLeft.length);
                    NSRange range = [dataLeft rangeOfData:protocolHeadData options:NSDataSearchBackwards range:NSMakeRange(0, dataLeft.length)];
     
                    if (range.location != NSNotFound)
                    {
                        LHLog(@"!!!!!addObject DataLength:%ld",dataLeft.length);
                        [self.receiveData addObject:dataLeft];
                    }
                    else
                    {
                        LHLog(@"!!!!!不合法的剩余数据,长度为:%ld",dataLeft.length);
                        //                        [self.receiveData removeAllObjects];
                    }
                }
                else
                {
                    LHLog(@"!!!!!不合法的剩余数据,长度为:%ld",dataLeft.length);
                    //                    [self.receiveData removeAllObjects];
                }
     
            }
     
     
        }
    }
    else
    {
        LHLog(@"!!!!!unknow data,长度为:%ld",data.length);
        NSRange range = [data rangeOfData:protocolHeadData options:NSDataSearchBackwards range:NSMakeRange(0, data.length)];
        if (range.location != NSNotFound) {
            NSData *dataSub = [data subdataWithRange:NSMakeRange(range.location, data.length-range.location)];
            LHLog(@"!!!!!new data:%ld",dataSub.length);
            [self.receiveData addObject:dataSub];
        }
        else
        {
            [self.receiveData addObject:data];
        }
    }

 */
}
@end
